/*
 * lfs_protocol.c
 *
 *  Created on: Jan 13, 2013
 *      Author: red chen
 */
#include <string.h>
#include <emalloc.h>
#include <map.h>
#include <buffer.h>
#include "lfs_protocol.h"

typedef struct
{
    Map* mapping;
} LFSProtocol;

void lfs_protocol_init()
{

}

int lfs_protocol_deserialize(const char* method, Buffer* req_buf, Buffer* resp_buf, void** input, void** output)
{
    /*----------------------------*/
    /*Use map for this in future*/
    /*----------------------------*/
    if (strcmp(method, MASTER_HANDLER_FILE_META) == 0)
    {

    }
    else if (strcmp(method, MASTER_HANDLER_FILE_CREATE) == 0)
    {
        *input = emalloc(sizeof(FileCreateRequest));
        *output = emalloc(sizeof(FileCreateResponse));
        if (req_buf != NULL)
        {
            file_create_request_deserialize(req_buf, *input);
        }
        if (resp_buf != NULL)
        {
            file_create_response_deserialize(resp_buf, *output);
        }
    }
    else if (strcmp(method, MASTER_HANDLER_FILE_WRITE) == 0)
    {
    }
    else if (strcmp(method, MASTER_HANDLER_FILE_DELETE) == 0)
    {
    }
    else if (strcmp(method, MASTER_HANDLER_FILE_META_UPDATE) == 0)
    {
    }
    else if (strcmp(method, CHUNKSERVER_HANDLER_ADD_CHUNK) == 0)
    {
        *input = emalloc(sizeof(AddChunkRequest));
        *output = emalloc(sizeof(AddChunkResponse));
        if (req_buf != NULL)
        {
            add_chunk_request_deserialize(req_buf, *input);
        }
        if (resp_buf != NULL)
        {
            add_chunk_response_deserialize(resp_buf, *output);
        }
    }
    return 1;
}

int lfs_protocol_serialize(const char* method, void* input, void* output, Buffer* req, Buffer* resp)
{
    if (strcmp(method, MASTER_HANDLER_FILE_META) == 0)
    {

    }
    else if (strcmp(method, MASTER_HANDLER_FILE_CREATE) == 0)
    {
        if (input != NULL)
        {
            file_create_request_serialize(input, req);
        }
        if (output != NULL)
        {
            file_create_response_serialize(output, resp);
        }
    }
    else if (strcmp(method, MASTER_HANDLER_FILE_WRITE) == 0)
    {
    }
    else if (strcmp(method, MASTER_HANDLER_FILE_DELETE) == 0)
    {
    }
    else if (strcmp(method, CHUNKSERVER_HANDLER_ADD_CHUNK) == 0)
    {
        if (input != NULL)
        {
            add_chunk_request_serialize(input, req);
        }
        if (output != NULL)
        {
            add_chunk_response_serialize(output, resp);
        }
    }
    return 1;
}

//

void file_create_request_serialize(FileCreateRequest* request, Buffer* buf)
{
    buffer_write(buf, request->filename, sizeof(request->filename));
    buffer_write(buf, &request->min_replica, sizeof(request->min_replica));
    buffer_write(buf, &request->max_replica, sizeof(request->max_replica));
}

void file_create_request_deserialize(Buffer* buf, FileCreateRequest* request)
{
    buffer_read(buf, request->filename, sizeof(request->filename));
    buffer_read(buf, &request->min_replica, sizeof(request->min_replica));
    buffer_read(buf, &request->max_replica, sizeof(request->max_replica));
}

void file_create_response_serialize(FileCreateResponse* response, Buffer* buf)
{
    buffer_write(buf, &response->status, sizeof(response->status));
}

void file_create_response_deserialize(Buffer* buf, FileCreateResponse* response)
{
    buffer_read(buf, &response->status, sizeof(response->status));
}

//

void add_chunk_request_serialize(AddChunkRequest* request, Buffer* buf)
{
    buffer_write(buf, request->filename, sizeof(request->filename));
    buffer_write(buf, &request->id, sizeof(request->id));
    buffer_write(buf, &request->size, sizeof(request->size));
}

void add_chunk_request_deserialize(Buffer* buf, AddChunkRequest* request)
{
    buffer_read(buf, request->filename, sizeof(request->filename));
    buffer_read(buf, &request->id, sizeof(request->id));
    buffer_read(buf, &request->size, sizeof(request->size));
}

void add_chunk_response_serialize(AddChunkResponse* response, Buffer* buf)
{
    buffer_write(buf, &response->status, sizeof(response->status));
}

void add_chunk_response_deserialize(Buffer* buf, AddChunkResponse* response)
{
    buffer_read(buf, &response->status, sizeof(response->status));
}

